`timescale 1ns/1ps
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// *********************************************************************************
// Project Name : 
// Author       : Dark
// Create Time  : 2023-02-04 09:31:09
// Revise Time  : 2023-02-04 09:31:09
// File Name    : mycpu.sv
// Abstract     :  use for verilator
`include "defines.svh"
module mycpu(
  input clk,                //
  input rst_n,              //

  output logic done         //0xdead10cc
);

//=================================================================================
// Parameter declaration
//=================================================================================
localparam MAXCYCLE = 1000;

//=================================================================================
// Signal declaration
//=================================================================================
logic [31:0] numcycles;
enum reg [3:0]{IDLE=4'b0001,DONE=4'b0010,PROCESS=4'b0100,AWAIT=4'b1000} state;
logic [300:1] testcase;   //
logic [5:0] cnt_wait;

logic [31:0] x3;
logic [31:0] x26;
logic [31:0] x27;
  assign x3 =inst_riscv_core.inst_regfile.regbank[3];
  assign x26 = inst_riscv_core.inst_regfile.regbank[26];
  assign x27 =inst_riscv_core.inst_regfile.regbank[27];
//=================================================================================
// Main declaration
//=================================================================================

initial begin
  testcase = "./sim/generated/rv32ui-p-add" ;
end


always @(posedge clk) begin
  if(rst_n == 1'b0) begin
    $readmemh({testcase, ".txt"},inst_riscv_core.inst_itcm.inst_ram.mem);
    $readmemh({testcase, ".mem"},inst_riscv_core.inst_dtcm.inst_ram.mem);
    $display("~~~ Begin test case < %0s >~~~", testcase);
  end
end



always @(posedge clk) 
  if(~rst_n) 
    numcycles <= 32'b0; 
  else if(!done) begin
    numcycles <= numcycles + 1'b1;
      // output the state of every instruction
    $display("cycle=%d, pc=%h, instruct=%h, rs1=%h,rs2=%h, rd=%h, imm=%h",
              numcycles,  
              inst_riscv_core.PC, 
              inst_riscv_core.instr,
              inst_riscv_core.rs1_addr,
              inst_riscv_core.rs2_addr,
              inst_riscv_core.wr_reg_addr,
              inst_riscv_core.imm);
  end

always @(posedge clk) begin 
  if(~rst_n) 
    done <= 1'b0; 
  else case (state)
        IDLE    : if (rst_n)
                  begin
                      done  <= 1'b0; 
                      state <= PROCESS ;
                      cnt_wait <= 6'b0;
                  end
        PROCESS : if(  (x26 != 32'b1) && (numcycles<MAXCYCLE) )
                  state <= PROCESS ;  
                  else 
                  state <= AWAIT ; 
        AWAIT   : begin
                    if(cnt_wait == 6'd10)
                      state <= DONE ;  
                    else 
                      begin
                      state <= AWAIT ;  
                      cnt_wait <= cnt_wait + 1'b1;                          
                      end 
                  end                 
        DONE    : begin
                  done  <= 1'b1;                      
      if(numcycles>MAXCYCLE)
        begin
      $display("############################");
      $display("########  fail  !!!#########");
      $display("############################");
      $display("!!!Error:test case %0s does not terminate!", testcase);
        end    
      else if(x27==32'd1)
          begin
      $display("############################");
      $display("########  pass  !!!#########");
      $display("############################");
      $display("OK:test case %0s finshed OK at cycle %d.",
                    testcase, numcycles-1);
          end  
      else
          begin
      $display("############################");
      $display("########  fail  !!!#########");
      $display("############################");
      $display("test case %0s  error in cycle %d. fail testnum = %2d",
                testcase, numcycles-1,x3);
          end
    end                
    default :     state <= IDLE; 
  endcase 
end

//=================================================================================
// Instantiation declaration
//=================================================================================
riscv_core inst_riscv_core (.sys_clk(clk), .sys_rst_n(rst_n));


endmodule

